Русская справка по Delphi 5
Мастерская Delphi программирования.
Главная Мастерская Архив Ссылки Отдых Для гостей  
Секреты VCL Секреты API            

Рисуем прозрачную картинку.

пример: trbmp.zip

Иногда возникает ситуация когда, необходимо сделать рисунок прозрачным, то есть удалить его фон. Сталкнувшись с такой проблемой, пришлось немного покопать MSDN. В результате получилась тестовая программа, которая использует несколько способов добиться желаемого результата.


Полностью исходный код можно посмотреть здесь

Рассмотрим подробнее способы решения задачи.
Способ None
Ничего не делает. Восстанавливает рисунок загружая его из ресурса.

Способ MSDN.
Был найден в MSDN Id: Q79212. Суть его в манипулировании изображением с помощью функции BitBlt. Способ реализован в процедуре TransparentBmp.
Вот исходный код:

procedure TForm1.TransparentBmp(Dc: HDC; Bitmap: HBitmap; xStart: Integer;
 yStart: Integer; trColor: TColor);
  • Dc - контекст устройства на котором будем рисовать. В нашем случае - Канва формы.
  • Bitmap - картинка, которую рисуем.
  • xStart, yStart - координаты точки начала отрисовки.
  • trColor - цвет фона который требуется удалить.
var bm: Windows.TBitmap;
    hDcTemp: HDC;
    ptSize: TPoint;
    hDcBack, hDcObject, hDcMem, hDcSave: hDc;
    bmAndBack, bmAndObject, bmAndMem, bmSave: HBitmap;
    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld: HBitmap;
    sColor: TColorRef;
begin
 hDcTemp := CreateCompatibleDc(Dc);
 SelectObject(hDcTemp,Bitmap);
 GetObject(Bitmap,Sizeof(bm),@bm);
 ptSize.x := bm.bmWidth;
 ptSize.y := bm.bmHeight;
 hDcBack := CreateCompatibleDc(Dc);
 hDcObject := CreateCompatibleDc(Dc);
 hDcMem := CreateCompatibleDc(Dc);
 hDcSave := CreateCompatibleDc(Dc);
 bmAndBack := CreateBitmap(ptSize.x,ptSize.y,1,1,nil);
 bmAndObject := CreateBitmap(ptSize.x,ptSize.y,1,1,nil);
 bmAndMem := CreateCompatibleBitmap(Dc,ptSize.x,ptSize.y);
 bmSave :=  CreateCompatibleBitmap(Dc,ptSize.x,ptSize.y);
 bmBackOld := SelectObject(hDcBack,bmAndBack);
 bmObjectOld := SelectObject(hDcObject,bmAndObject);
 bmMemOld := SelectObject(hDcMem,bmAndMem);
 bmSaveOld := SelectObject(hDcSave,bmSave);
 SetMapMode(hDcTemp,GetMapMode(Dc));
 BitBlt(HDcSave,0,0,ptSize.x,ptSize.y,HDcTemp,0,0,SRCCOPY);
 sColor := SetBkColor(hDcTemp,trColor);
 BitBlt(hDcObject,0,0,ptSize.x,ptSize.y,hDcTemp,0,0,SRCCOPY);
 SetBkColor(hDcTemp,sColor);
 BitBlt(hDcBack,0,0,ptSize.x,ptSize.y,hDcObject,0,0,NOTSRCCOPY);
 BitBlt(hDcMem,0,0,ptSize.x,ptSize.y,Dc,xStart,yStart,SRCCOPY);
 BitBlt(hDcMem,0,0,ptSize.x,ptSize.y,hDcObject,0,0,SRCAND);
 BitBlt(hDcTemp,0,0,ptSize.x,ptSize.y,hDcBack,0,0,SRCAND);
 BitBlt(hDcMem,0,0,ptSize.x,ptSize.y,hDcTemp,0,0,SRCPAINT);
 BitBlt(Dc,xStart,yStart,ptSize.x,ptSize.y,hDcMem,0,0,SRCCOPY);
 BitBlt(hDcTemp,0,0,ptSize.x,ptSize.y,hDcSave,0,0,SRCCopy);
 DeleteObject(SelectObject(hDcBack,bmBackOld));
 DeleteObject(SelectObject(hDcObject,bmObjectOld));
 DeleteObject(SelectObject(hDcMem,bmMemOld));
 DeleteObject(SelectObject(hDcSave,bmSaveOld));
 DeleteDc(hDcBack);
 DeleteDc(hDcObject);
 DeleteDc(hDcMem);
 DeleteDc(hDcSave);
 DeleteDc(hDcTemp);
end;

Здесь создается Маска. Накладывается на картинку. В результате фон удаляется. Думаю тоже самое делается в способе Win98, только он скрыт от нас внутри системы.

Способ Win98
Здесь используется новая функция появившаяся в windows98 - TransparentBlt. Чтобы ее использовать необходима библиотека msimg32.dll.

 TransparentBlt(Canvas.Handle,10,10,100,100,Bmp.Canvas.Handle,0,0,bmp.Width,
 bmp.Height,clWhite);

Существует еще два способа сделать рисунок прозрачным, которые не использованы в тестовой программе.
Способ применимый только для Windows NT заключается в вызове функции MaskBlt. До вызова функции необходимо создать маску.
Способ из VCL Delphi5
Функция TransparentStratchBlt из модуля Graphics. Пример использования можно увидеть в реализации Canvas.BrushCopy.

пример: trbmp.zip


Главная Мастерская Архив Ссылки Отдых Для гостей  
Секреты VCL Секреты API            
Дизайн и программирование - Valler© ,2000,2001.
http://www.valler.narod.ru
Используются технологии uCoz